#!/bin/sh

e2e_test_install() {
  DBOPS_NAME=vacuum

  create_or_replace_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" 1

  wait_pods_running "$CLUSTER_NAMESPACE" 1
  wait_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"
}

e2e_test() {
  run_test "Checking that vacuum is working" check_vacuum_is_working

  run_test "Checking that vacuum full is working" check_vacuum_full_is_working

  run_test "Checking that vacuum freeze is working" check_vacuum_freeze_is_working

  run_test "Checking that vacuum analyze is working" check_vacuum_analyze_is_working

  run_test "Checking that vacuum with disable page skipping is working" check_vacuum_disable_page_skipping_is_working

  run_test "Checking that vacuum is working for specific databases" check_vacuum_specific_databases_is_working

  run_test "Checking that vacuum timeout works correctly" check_vacuum_timed_out
}

check_vacuum_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: vacuum
EOF

  wait_until eval '[ "$(kubectl get sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME" \
    --template "{{ .status.opRetries }}")" = "0" ]'
  kubectl get sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME" -o yaml > "$LOG_PATH/sgdbops.yaml"
  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
  kubectl create -f "$LOG_PATH/sgdbops.yaml"

  check_vacuum

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_vacuum_full_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: vacuum
  vacuum:
    full: true
EOF

  check_vacuum

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_vacuum_freeze_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: vacuum
  vacuum:
    freeze: true
EOF

  check_vacuum

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_vacuum_analyze_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: vacuum
  vacuum:
    analyze: true
EOF

  check_vacuum

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_vacuum_disable_page_skipping_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: vacuum
  vacuum:
    disablePageSkipping: true
EOF

  check_vacuum

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_vacuum_specific_databases_is_working() {
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" \
    -q "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'template1' AND pid != pg_backend_pid()"
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" \
    -q "CREATE DATABASE test1"
  run_query -p 5432 -h "$CLUSTER_NAME" -n "$CLUSTER_NAMESPACE" -c "$CLUSTER_NAME" \
    -q "CREATE DATABASE test2;"
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: vacuum
  vacuum:
    databases:
    - name: test1
      full: true
    - name: test2
      analyze: true
EOF

  check_vacuum

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_vacuum() {
  assert_dbops_running "$DBOPS_NAME" "$CLUSTER_NAMESPACE"

  assert_dbops_completion "$DBOPS_NAME" "$CLUSTER_NAMESPACE"

  if [ "$(kubectl get -n "$CLUSTER_NAMESPACE" job \
    -l "stackgres.io/dbops-name=$DBOPS_NAME,stackgres.io/db-ops=true" \
    -o name 2>/dev/null | wc -l)" = 1 ]
  then
    success "vacuum job was not removed after completion."
  else
    fail "vacuum job was removed after completion."
  fi
}

check_vacuum_timed_out() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: vacuum
  timeout: PT1S
  vacuum:
    full: true
    analyze: true
EOF

  if kubectl wait --timeout "${E2E_TIMEOUT}s" -n "$CLUSTER_NAMESPACE" sgdbops "$DBOPS_NAME" \
    --for condition=Completed \
    && kubectl wait --timeout "0s" -n "$CLUSTER_NAMESPACE" sgdbops "$DBOPS_NAME" \
    --for condition=Failed
  then
    success "vacuum failed."
  else
    fail "vacuum did not fail."
  fi

  if [ "$(kubectl get -n "$CLUSTER_NAMESPACE" job \
    -l "stackgres.io/dbops-name=$DBOPS_NAME,stackgres.io/db-ops=true" \
    -o name 2>/dev/null | wc -l)" = 1 ]
  then
    success "vacuum job was not removed after failure."
  else
    fail "vacuum job was removed after failure."
  fi

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"

  if wait_until eval '[ "$(kubectl get -n "$CLUSTER_NAMESPACE" job \
    -l "stackgres.io/dbops-name=$DBOPS_NAME,stackgres.io/db-ops=true" \
    -o name 2>/dev/null | wc -l)" = 0 ]'
  then
    success "vacuum job was removed after sgdbops was removed."
  else
    fail "vacuum job was not removed after sgdbops was removed."
  fi
}
